package com.itheima.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.dao.CategoryDao;
import com.itheima.reggie.dao.DishDao;
import com.itheima.reggie.dao.SetmealDao;
import com.itheima.reggie.dao.SetmealDishDao;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.entity.dto.SetmealDto;
import com.itheima.reggie.entity.vo.SetmealDishVo;
import com.itheima.reggie.exception.CustomerException;
import com.itheima.reggie.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired(required = false)
    private SetmealDao setmealDao;

    @Autowired(required = false)
    private SetmealDishDao setmealDishDao;

    @Autowired(required = false)
    private CategoryDao categoryDao;

    @Override
    @Transactional
    @CacheEvict(value = "setmealCache",allEntries = true) // allEntries = true 表示该value名称空间下的所有缓存全部清除
    public void save(SetmealDto setmealDto) {
        // 1.给套餐的信息补全参数（创建时间，修改时间，状态）
        setmealDto.setCreateTime(LocalDateTime.now());
        setmealDto.setUpdateTime(LocalDateTime.now());
        setmealDto.setStatus(1); // 启售
        setmealDao.save(setmealDto); // 由于下面需要使用套餐的id，所以插入之后记得返回主键


        // 2. 给套餐的菜品补全参数
        List<SetmealDish> dishList = setmealDto.getSetmealDishes();
        for (SetmealDish setmealDish : dishList) {
            // 所属的套餐
            setmealDish.setSetmealId(setmealDto.getId());
            setmealDish.setSort(0);
            setmealDish.setCreateTime(setmealDto.getCreateTime());
            setmealDish.setUpdateTime(setmealDto.getUpdateTime());
            setmealDish.setCreateUser(setmealDto.getCreateUser());
            setmealDish.setUpdateUser(setmealDto.getUpdateUser());
        }

        setmealDishDao.batchSave(dishList);
    }

    @Override
    public Page<SetmealDto> findByPage(Integer page, Integer pageSize, String name) {
        // 1.设置当前页与页面的大小
        PageHelper.startPage(page,pageSize);
        // 2.来查询页面所需要的数据
        List<Setmeal> setmealList = setmealDao.findByName(name);
        // 3.得到PageInfo对象，这是pageInfo里面存储的是SetMeal，我们需要的是SetMealDto
        PageInfo<Setmeal> pageInfo = new PageInfo<>(setmealList);
        // 4.从pageInfo中取出SetMeal，然后转换为SetMealDto
        List<SetmealDto> setmealDtoList = setmealList.stream().map(setmeal -> {
            SetmealDto setmealDto = new SetmealDto();
            // 属性拷贝
            BeanUtils.copyProperties(setmeal, setmealDto);
            // 查询套餐的类别
            Category category = categoryDao.findById(setmeal.getCategoryId());
            setmealDto.setCategoryName(category.getName());
            return setmealDto;
        }).collect(Collectors.toList());
        // 5.构建page对象
        Page<SetmealDto> pageResult = new Page<>(setmealDtoList,pageInfo.getTotal(),pageInfo.getPageSize(),pageInfo.getPageNum());
        return pageResult;
    }

    @Override
    @Transactional
    public void deleteByIds(List<Long> ids) {
        // 检查要删除的套餐是否是起售的，如果是在售状态不允许被删除
        int count = setmealDao.findCountByIds(ids);
        if (count>0){
            throw new CustomerException("套餐目前处于在售状态，无法直接删除！");
        }
        // 删除套餐
        setmealDao.deleteByIds(ids);

        // 删除套餐对应的菜品
        setmealDishDao.deleBySetMealIds(ids);
    }

    @Override
    @Cacheable(value = "setmealCache",key = "#categoryId+'_'+#status")
    public List<SetmealDto> list(Long categoryId, Integer status) {

        List<Setmeal>setmealList = setmealDao.list(categoryId,status);
        //转成dto
        List<SetmealDto> setmealDtoList = setmealList.stream().map(setmeal -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);
            // 查询套餐对应的菜品
            List<SetmealDish> setmealDishList = setmealDishDao.findBySetmealId(setmeal.getId());
            setmealDto.setSetmealDishes(setmealDishList);
            return setmealDto;
        }).collect(Collectors.toList());
        return setmealDtoList;

    }

    @Autowired(required = false)
    private DishDao dishDao;

    @Override
    public List<SetmealDishVo> setmealDishList(Long setmealId) {
        List<SetmealDish> setmealDishList = setmealDishDao.findBySetmealId(setmealId);
        List<SetmealDishVo> setmealDishVos = setmealDishList.stream().map(setmealDish -> {
            SetmealDishVo setmealDishVo = new SetmealDishVo();
            BeanUtils.copyProperties(setmealDish, setmealDishVo);
            // 查找菜品
            Dish dish = dishDao.findById(setmealDish.getDishId());
            setmealDishVo.setImage(dish.getImage());
            return setmealDishVo;
        }).collect(Collectors.toList());
        return setmealDishVos;
    }
}
